package org.pitest.project.impl;

import org.pitest.mutationtest.ReportOptions;
import org.pitest.mutationtest.commandline.OptionsParser;
import org.pitest.mutationtest.commandline.ParseResult;
import org.pitest.project.ProjectConfigurationException;
import org.pitest.project.ProjectConfigurationParser;
import org.pitest.project.ProjectConfigurationParserException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * An implementation of the {@see ProjectConfigurationParser} interface that will load all configuration
 * options from a file, rather than the command line.
 * <p/>
 * The file format is the same format as the command line options, just specified in a file rather than as
 * arguments. This format can be used to get around command line argument length issues (mainly encountered
 * on earlier versions of windows).
 * <p/>
 * Each argument should be specified on a new line, blank lines and any line starting with a {@code '#'} are ignored.
 * <p/>
 * As this class just loads the file and redirects it to the {@see OptionsParser}, any changes to the command line should
 * automatically be included.
 *
 * @author Aidan Morgan
 */
public class CommandFileConfigurationParser implements ProjectConfigurationParser {
  /**
   * @inheritDoc
   */
  public ReportOptions loadProject(String project) throws ProjectConfigurationParserException, ProjectConfigurationException {
    try {
      // load the file as one continuous string, separated by spaces.
      String[] options = loadPropertiesFromFile(project);

      // use the standard command line parser implementation to parse the contents of the file.
      OptionsParser parser = new OptionsParser();
      ParseResult pr = parser.parse(options);

      return pr.getOptions();
    } catch (IOException e) {
      throw new ProjectConfigurationParserException("Cannot load configuration from file " + project + ".", e);
    }
  }

  private String[] loadPropertiesFromFile(String project) throws IOException {
    File f = new File(project);

    BufferedReader br = null;

    try {
      br = new BufferedReader(new FileReader(f));

      StringBuilder buffer = new StringBuilder();

      String input = null;

      // read the file in and make it appear as one continuous line...
      while ((input = br.readLine()) != null) {
        String trimmed = input.trim();

        // ignore any lines that are blank.
        if (trimmed.length() > 0 && !trimmed.startsWith("#")) {
          buffer.append(input);
          buffer.append(" ");
        }
      }

      // split on any whitespace (make it look like a command line)
      return buffer.toString().split(" ");
    } finally {
      if (br != null) {
        br.close();
      }
    }
  }
}
